package persistence;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 * 
 * Track enthält die Information über die Datei. <br>
 * Im Konstruktor wird ein AudioStream angelegt <br>
 * der dann den Decoder für mp3-Files ausgibt.
 *
 * @author Patrick
 * @sinde 30.11.2011
 *
 */
public class Track implements Serializable{

	private static final long serialVersionUID = 1L;
	private static AudioFormat decodedFormat;
	private static AudioFormat baseFormat;
	private AudioInputStream in;
	private File file;
	
	/**
	 * Erzeugen eines Tracks über einen String Pfad zum Track.
	 * 
	 * @author Patrick
	 * @since 30.11.2011
	 * @param path
	 * @throws UnsupportedAudioFileException
	 * @throws IOException
	 */
	public Track(String path) throws UnsupportedAudioFileException, IOException{
		this(new File(path));
	}
	
	/**
	 * Erzeugen eines Tracks über ein File Objekt.
	 * 
	 * @author Patrick
	 * @since 30.11.2011
	 * @param file
	 * @throws UnsupportedAudioFileException
	 * @throws IOException
	 */
	public Track(File file) throws UnsupportedAudioFileException, IOException {
		this.file = file;
		in = AudioSystem.getAudioInputStream(this.file);
		baseFormat = in.getFormat();
		decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
				baseFormat.getSampleRate(), 16, baseFormat.getChannels(),
				baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
		
	}

	/**
	 * Kopierkonstruktor
	 * 
	 * @author Patrick
	 * @since 30.11.2011
	 * @param track
	 * @throws UnsupportedAudioFileException
	 * @throws IOException
	 */
	public Track(Track track) throws UnsupportedAudioFileException, IOException {
		this(track.getFile());
	}

	/**
	 * gibt das File vom Track zurück
	 *
	 * @author Patrick
	 * @since 30.11.2011
	 *
	 * @return
	 */
	public File getFile() {
		return this.file;
	}

	/**
	 * Erzeugt einen SourceDataLine was später unsere Ausgabe übernimmt.
	 *
	 * @author Patrick
	 * @since 30.11.2011
	 *
	 * @param audioFormat
	 * @return
	 * @throws LineUnavailableException
	 */
	public SourceDataLine getLine(AudioFormat audioFormat)
			throws LineUnavailableException {
		SourceDataLine res = null;
		DataLine.Info info = new DataLine.Info(SourceDataLine.class,
				audioFormat);
		res = (SourceDataLine) AudioSystem.getLine(info);
		res.open(audioFormat);
		return res;
	}

	/**
	 * Erzuegt das DecodierFormat für mp3-Datein
	 *
	 * @author Patrick
	 * @since 30.11.2011
	 *
	 * @return
	 */
	public AudioFormat getDecodedFormat() {
		return Track.decodedFormat;
	}
	
	/**
	 * Gibt den InutStream zurück aus dem Später gelesen <br>
	 * wird nachdem er Decodiert ist.
	 *
	 * @author Patrick
	 * @since 30.11.2011
	 *
	 * @return
	 */
	public AudioInputStream getTrackInputStream(){
		return this.in;
	}

	@Override
	/**
	 * 
	 * @author Patrick
	 * @since 30.11.2011
	 *
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		return this.file.hashCode();
	}

	@Override
	/**
	 * 
	 * @author Patrick
	 * @since 30.11.2011
	 *
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object obj) {
		
		if(obj != null){
			Track track;
			if(obj instanceof Track){
				track = (Track) obj;
				if(!track.file.equals(this.file)){
					return false;
				}
			}else{
				return false;
			}
			return true;
		}else{
			return false;
		}
	}

	public String getName(){
		return this.file.getName();
	}
	
	@Override
	/**
	 * 
	 * @author Patrick
	 * @since 30.11.2011
	 *
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return this.file.getAbsolutePath();
	}
}
